<?php
/**
 * Created by PhpStorm.
 * User: zjx
 * Date: 2016/11/25
 * Time: 10:32
 */

namespace App\Services\Utils;

use App\Exceptions\ApiErrCode;
use App\Providers\AppServiceProvider;
use Illuminate\Http\Response;

trait ApiResponser
{
    /**
     *
     * @param mixed $compact_data
     * @param int $status
     * @param array $headers
     * @return array|\Illuminate\Http\Response
     */
    protected function response($compact_data, $status = Response::HTTP_OK, array $headers = [])
    {
        $content = $this->normalizeResponseData($compact_data);

        return response($content, $status, $headers);
    }

    /**
     * 可以传入 JSON 参数
     *
     * @param mixed $compact_data
     * @param int $json_option
     * @param int $status
     * @param array $headers
     * @return array|\Illuminate\Http\Response
     */
    protected function responseJson($compact_data, $json_option = 0, $status = Response::HTTP_OK, array $headers = [])
    {
        $content = $this->normalizeResponseData($compact_data);

        return response()->json($content, $status, $headers, $json_option);
    }

    /**
     * 处理返回数据变成数组，trait中的private不能在use trait 的类中调用，只能通过 trait 中的方法如 protect public 等方法）
     * 如果需要同名调用需要在 trait 中 __call
     *
     * @param mixed|array $compact_data
     *
     * @return array
     */
    private function normalizeResponseData($compact_data): array
    {
        $code = ['code' => ApiErrCode::API_CODE_OK];

        /** @var array $compact_data */
        $compact_data = is_array($compact_data)
            ? $compact_data
            : ['data' => $compact_data];

        $content = array_merge($code, $compact_data, $this->debugResponseInfo());

        return $content;
    }

    /**
     * @param $image
     * @param array $headers
     * @param int $status
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function responseImage($image, $headers = [], $status = Response::HTTP_OK)
    {
        $default_png_header = [
            'Content-Type' => 'image/png'
        ];
        
        return response($image, $status, $headers + $default_png_header);
    }

    /**
     * @param mixed $compact_data
     * @param array $headers
     * @return array|\Illuminate\Http\Response
     */
    protected function responseCreated($compact_data, array $headers = [])
    {
        return $this->response($compact_data, Response::HTTP_CREATED, $headers);
    }

    /**
     * @param mixed $compact_data
     * @param array $headers
     * @return array|\Illuminate\Http\Response
     */
    protected function responseAccepted($compact_data, array $headers = [])
    {
        return $this->response($compact_data, Response::HTTP_ACCEPTED, $headers);
    }

    /**
     * @return array
     */
    private function debugResponseInfo(): array
    {
        $info = [];
        if (! config('app.debug')) {
            return $info;
        }

        if (config('app.dump_sql')) {
            $info['debug']['sql_count'] = AppServiceProvider::sqlCount();
        }

        return $info;
    }
}